#pragma once
#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <string>
#include <functional>
#include "RingQueue.hpp"
#include "common.hpp"
// using namespace std;
// template<class T>
struct ThreadData
{
    std::string _name;
    // ...
    ThreadData(const std::string name)
        : _name(name)
    {
    }
};
// template<class T>
// using func_t = std::function<void(const std::string, T*)>;
template <class T>
using func_t = std::function<void(T&)>;
template <class T>
class Thread
{
public:
    Thread(T data, func_t<T> f)
        : _tid(0), _isrunning(false), _data(data), _f(f)
    {
    }

    bool Start()
    {
        int n = pthread_create(&_tid, nullptr, routine, this);
        if (n == 0)
        {
            _isrunning = true;
            return true;
        }
        return false;
    }
    static void *routine(void *args)
    {
        Thread *p = static_cast<Thread *>(args);
        p->_f(p->_data);
        return nullptr;
    }
    bool Join()
    {
        int ret = pthread_join(_tid, nullptr);
        if (ret == 0)
        {
            _isrunning = false;
            return true;
        }
        return false;
    }
    ~Thread() {}

private:
    pthread_t _tid;
    bool _isrunning;
    func_t<T> _f;
    T _data;
};


// template <class T>
// class Thread
// {
// public:
//     Thread(RingQueue<T> *rq)
//         : _tid(0), _isrunning(false), _rq(rq)
//     {
//     }

//     bool Start()
//     {
//         int n = pthread_create(&_tid, nullptr, routine, this);
//         if (n == 0)
//         {
//             _isrunning = true;
//             return true;
//         }
//         return false;
//     }
//     static void *routine(void *args)
//     {
//         Thread *p = static_cast<Thread *>(args);
//         while (1)
//         {
//             T t;
//             p->_rq->Pop(&t);
//             t();
//             std::cout << pthread_self() << ": " << t.GetResult() << "\n";
//         }
//         return nullptr;
//     }
//     bool Join()
//     {
//         int ret = pthread_join(_tid, nullptr);
//         if (ret == 0)
//         {
//             _isrunning = false;
//             return true;
//         }
//         return false;
//     }
//     ~Thread() {}

// private:
//     pthread_t _tid;
//     bool _isrunning;
//     RingQueue<T> *_rq;
// };